'use strict';
const csv = require('csv');
const fs = require('fs');
const Promise = require('bluebird');
const _ = require('lodash');
const http = require('http');
const mkdirp = require('mkdirp');
const path = require('path');
const async = require('async');

const outputDir = 'out';
mkdirp.sync(outputDir);

function parse() {
    const filePath = 'pic.csv';
    return new Promise((resolve, reject) => {
        const parser = csv.parse({delimiter: ','}, (err, data) => {
            if (err) {
                reject(err);
                return ;
            }
            const urls = _.flatMap(data, line => {
                return line;
            }).filter(url => url.length !== 0);
            resolve(urls);
        });
       fs.createReadStream(path.join(__dirname, filePath)).pipe(parser);
    });
}

function download(urls) {
    const tasks = urls.map(url => {
        return cb => {
            const arrs = url.split('/');
            const filename = arrs[arrs.length - 1];
            url = 'http://' + url;
            const outPath = path.join(__dirname, outputDir, filename);
            http.get(url, (res) => {
                const statusCode = res.statusCode;
                if (statusCode !== 200) {
                    console.error(`download ${url} fail, code ${statusCode}`);
                    cb(null);
                    return ;
                }
                const outStream = fs.createWriteStream(outPath);
                res.pipe(outStream);
                outStream.on('close', () => {
                    console.log(`download ${url} success`);
                    cb();
                });
            }).on('error', (e) => {
                console.error(`download ${url} fail, error `, e);
            });
        };
    });
    return new Promise(resolve => {
        async.parallelLimit(tasks, 10, () => {
            resolve();
        });
    });
}

parse().then(download).then(() => {
    console.log('success');
    process.exit(0);
}).catch(err => {
    console.error('err', err);
    process.exit(1);
});